package com.hyjx.framework.common.interceptor;

import com.hyjx.framework.service.ConfigManager;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * XSS 过滤器
 */

public class XSSFilter implements Filter {
    private static Map<String, String> xssMap = null;
    
    static {
        xssMap = new LinkedHashMap<String, String>();
        String filtersAndReslvoesStr = ConfigManager.getConfig("xssIntereptor.resolver");
        String filtersAndReslvoes[] = filtersAndReslvoesStr.split("=");
        for (String str : filtersAndReslvoes) {
            xssMap.put(str.split(",")[0], str.split(",").length == 2 ? str.split(",")[1] : "");
        }
    }
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 强制类型转换 HttpServletRequest
        HttpServletRequest httpReq = (HttpServletRequest) request;
        // 构造HttpRequestWrapper对象处理XSS
        String url = httpReq.getRequestURI().toLowerCase();
        String ignorePattern = ConfigManager.getConfig("xssIntereptor.ignorePattern");
        if (ignorePattern != null && ignorePattern.trim().length() > 0) {
            Pattern p = Pattern.compile(ignorePattern);
            Matcher m = p.matcher(url);
            if (m.find()) {
                chain.doFilter(httpReq, response);
                return;
            } else {
                HttpRequestWrapperTow httpReqWarp = new HttpRequestWrapperTow(httpReq, xssMap);
                chain.doFilter(httpReqWarp, response);
            }
        }
        
        Enumeration params = request.getParameterNames();
        while (params.hasMoreElements()) {
            // 得到参数名
            String name = params.nextElement().toString();
            // "--");
            // 得到参数对应值， 这样写不对啊！！容易误杀。
            // answer: 我错了，涛哥，已改
            // names.append(name);
            if (sqlValidate(name)) {
                response.setContentType("text/html;charset=UTF-8");
                //response.reset();
                
                response.getOutputStream().write("非法访问(sql1)!".getBytes("utf-8"));
                response.getOutputStream().flush();
                response.getOutputStream().close();
                return;
            }
            String[] value = request.getParameterValues(name);
            for (int i = 0; i < value.length; i++) {
                if (sqlValidate(value[i])) {
                    response.setContentType("text/html;charset=UTF-8");
                    response.getOutputStream().write("非法访问(sql2)!".getBytes("utf-8"));
                    response.getOutputStream().flush();
                    response.getOutputStream().close();
                    return;
                }
            }
        }
    }
    
    protected static boolean sqlValidate(String str) {
        str = str.toLowerCase();// 统一转为小写
        if ("".equals(str)) {
            return false;
        }
        String badStr = ConfigManager.getConfig("sql.filterSql");
        if (badStr == null || "".equals(badStr)) {
            return false;
        }
        String[] badStrs = badStr.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) >= 0) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 过滤器的初始化方法，系统启动时执行
     *
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        /*
		 * //过滤alert(); xssMap.put("alert\\((.*)\\)", ""); // 含有脚本： script
		 * xssMap.put("[s|S][c|C][r|R][i|C][p|P][t|T]", ""); // 含有脚本 javascript
		 * xssMap.put(
		 * "[\\\"\\\'][\\s]*[j|J][a|A][v|V][a|A][s|S][c|C][r|R][i|I][p|P][t|T]:(.*)[\\\"\\\']",
		 * "\"\""); // 含有函数： eval xssMap.put("[e|E][v|V][a|A][l|L]\\((.*)\\)",
		 * ""); // 含有符号 < xssMap.put("<", "&lt;"); // 含有符号 > xssMap.put(">",
		 * "&gt;"); // 含有符号 ( xssMap.put("\\(", "("); // 含有符号 )
		 * xssMap.put("\\)", ")"); // 含有符号 ' xssMap.put("\'", "\'"); // 含有符号 "
		 * xssMap.put("\"", "\"");
		 * --》解析已转移到 doFilter 中
		 */
    }
}